#include "MagGraphicsView.h"
#include <vector>


MagGraphicsView::MagGraphicsView(QWidget *parent) : QGraphicsView(parent), lastPos(QPoint())
{
    scene = new QGraphicsScene();
    setScene(scene); // 设置视图使用的场景
    setRenderHint(QPainter::Antialiasing); // 设置渲染选项，启用反锯齿
    setRenderHint(QPainter::SmoothPixmapTransform); // 设置渲染选项，平滑变换像素图案

    viewport()->installEventFilter(this); // 在视口上安装事件过滤器

    coordinateLabel = new QLabel("Mouse Coordinate: (0, 0)", this); // 创建并初始化鼠标坐标标签
    coordinateLabel->setGeometry(10, 10, 200, 20); // 设置鼠标坐标标签的位置和大小

}

MagGraphicsView::~MagGraphicsView(){}

void MagGraphicsView::addPoint(QList<QPointF> Points){
    // double radius{0.01};
    // scene->addEllipse(Points[0].rx()-radius, Points[0].ry()-radius, 2*radius, 2*radius, QPen(Qt::red), QBrush(Qt::red));
    // double diameter = 0.2;
    // QPointF topLeftPoint = Points[0] - QPointF(diameter / 2, diameter / 2);

    // // 创建一个红色的实心圆
    // QGraphicsEllipseItem *circleItem = new QGraphicsEllipseItem(QRectF(topLeftPoint, QSizeF(diameter, diameter)));
    // circleItem->setBrush(QBrush(Qt::red));
    // circleItem->setPen(Qt::NoPen);  // 禁用边框

    // // 将圆添加到场景中
    // scene->addItem(circleItem);
}


void MagGraphicsView::addLine(QList<QLineF> Lines){
    QPen pen(Qt::red); // 创建黑色画笔
    pen.setWidthF(0.01); // 设置线宽为2
    QLineF line;
    for(auto line:Lines){
        line = QLineF{line};
        scene->addLine(line, pen);
    }
}

void MagGraphicsView::addRriangle(QList<QPointF> Points){
    QPolygonF Triangle = QPolygonF{Points};
    QPen pen(Qt::black); // 创建黑色画笔
    pen.setWidthF(0); // 设置线宽为2
    scene->addPolygon(Triangle, pen);
}


void MagGraphicsView::wheelEvent(QWheelEvent *event) // 重写鼠标滚轮事件处理函数
{
    setTransformationAnchor(QGraphicsView::AnchorUnderMouse); // 设置转换锚点为鼠标位置
    qreal scaleFactor = 1.15; // 缩放因子
    if (event->angleDelta().y() < 0) // 判断滚轮滚动方向
        scaleFactor = 1.0 / scaleFactor;
    scale(scaleFactor, scaleFactor); // 进行缩放变换
}


void MagGraphicsView::mousePressEvent(QMouseEvent *event) // 重写鼠标按下事件处理函数
{
    if (event->button() == Qt::RightButton) { // 判断是否右键点击
        lastPos = event->pos(); // 记录鼠标位置
    }
    QGraphicsView::mousePressEvent(event); // 调用父类事件处理函数
}

void MagGraphicsView::mouseMoveEvent(QMouseEvent *event) // 重写鼠标移动事件处理函数
{
    if ((event->buttons() & Qt::RightButton)) { // 判断是否按住右键移动
        QPointF delta = event->pos() - lastPos; // 计算鼠标移动距离
        translate(delta.x(), delta.y()); // 执行平移变换
        lastPos = event->pos(); // 更新鼠标位置
    }
    QGraphicsView::mouseMoveEvent(event); // 调用父类事件处理函数
}

void MagGraphicsView::mouseReleaseEvent(QMouseEvent *event) // 重写鼠标释放事件处理函数
{
    if (event->button() == Qt::RightButton) { // 判断是否右键释放
        lastPos = QPoint(); // 清空鼠标位置记录
    }
    QGraphicsView::mouseReleaseEvent(event); // 调用父类事件处理函数
}

bool MagGraphicsView::eventFilter(QObject *obj, QEvent *event) // 重写事件过滤器处理函数
{
    if (event->type() == QEvent::MouseMove) { // 如果是鼠标移动事件
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        QPointF mousePos = mapToScene(mouseEvent->pos()); // 将视图坐标转换为场景坐标
        coordinateLabel->setText(QString("Mouse Coordinate: (%1, %2)")
                                     .arg(mousePos.x()).arg(-mousePos.y())); // 更新鼠标坐标标签内容
    }
    return false; // 返回false表示未拦截事件，交由对象自身处理
}

void MagGraphicsView::resizeGraphics(MagGraphicsView* ShowGraphics) // 改变图形大小的槽函数
{
    scene->setSceneRect(scene->itemsBoundingRect());

    // 设置视图的缩放策略
    ShowGraphics->setRenderHint(QPainter::Antialiasing);
    ShowGraphics->setRenderHint(QPainter::SmoothPixmapTransform);
    ShowGraphics->setAlignment(Qt::AlignCenter);
    ShowGraphics->setScene(scene);
    ShowGraphics->setDragMode(QGraphicsView::ScrollHandDrag);

    // 自动调整视图大小以适应场景
    ShowGraphics->fitInView(scene->sceneRect(), Qt::KeepAspectRatio);
}


void MagGraphicsView::showMesh(const GMesh& mesh) {
    clearCanvas();
    std::vector<std::vector<double>> coord = mesh.getcoord();
    std::vector<std::vector<uint>> element_S = mesh.getelement_S();

    for(uint i = 0; i < element_S.size(); i++){
        QList<QPointF> Points;
        for(uint j = 2; j < element_S[0].size(); j++){
            QPointF Point{coord[element_S[i][j]-1][1], coord[element_S[i][j]-1][2]};
            Points.append(Point);
        }
        addRriangle(Points);
        // ui->ShowGraphics->addTriangle();
    }
}

void MagGraphicsView::clearCanvas(){
    scene->clear();
}
